import { Device, GatewayType, Variable } from "@/api/interface/iot";
import { getDevice, modifyDevice, portDetect } from "@/api/modules/iot/device";
import modbus from "@/assets/images/iot/snapshot/5.png";
import OnlineStatus from "@/components/Sansan/Status/OnlineStatus";
import { EffectType, MessageType } from "@/enums/messageEnum";
import { useDialog } from "@/hooks/useDialog";
import router from "@/routers";
import { AuthBtns, SchemaNodeKey, modbusTcp } from "@/utils/constants";
import mittBus from "@/utils/mittBus";
import { confirm, exportExcel, showMsg, showTips } from "@/utils/util";
import GatewayBasicDialog from "@/views/iot/gateway/components/basicInfo/basicDialog";
import ProductBasicDialog from "@/views/iot/product/components/basicInfo/detailDialog";
import jsonpath from "jsonpath";
import { PropType } from "vue";
import { useRoute } from "vue-router";
import "../../model.scss";
import "./index.scss";
export default defineComponent({
	name: "Modbus", // 动态引入需要
	label: "Modbus", // 动态引入需要
	image: modbus, // 动态引入需要
	props: {
		isHmp: Boolean,
		is6210: Boolean,
		detail: {
			type: Object as PropType<Device.ResDeviceInfo | Device.ResProduct>,
			default() {
				return {};
			}
		}
	},
	setup(props) {
		const route = useRoute();
		const { gatewayDialog, productDialog } = useDialog();

		const state = reactive({
			detail: {} as Device.ResDeviceInfo
		});
		const variableEl = ref();
		//初始化设备信息
		const initDevice = async () => {
			if (route.query.sn) {
				let { result, code } = await getDevice({ idSn: route.query.sn });
				if (code == 200) {
					state.detail = result;
				} else {
					showMsg("未找到相关数据", MessageType.error);
					if (window.frames.length != parent.frames.length) return;
					timeOut.value = setTimeout(() => {
						router.go(-1);
					}, 3000);
				}
				variableEl.value.initLoad(state.detail);
			} else {
			}
		};
		onMounted(() => {
			initDevice();
		});
		//未找到设备数据时三秒后返回上级页面
		let timeOut = ref();
		//销毁定时器
		onBeforeUnmount(() => {
			clearInterval(timeOut.value);
			timeOut.value = "";
		});

		const basicDialog = reactive({
			title: "修改设备基本信息",
			visible: false
		});
		const setAddressDialog = reactive({
			title: "修改设备位置信息",
			visible: false
		});
		const submitBasic = async () => {
			let { code } = await modifyDevice({ ...state.detail });
			let ok = showTips(code, "修改设备");
			if (ok) {
				basicDialog.visible = false;
				setAddressDialog.visible = false;
				initDevice();
			}
		};

		//按钮事件
		const handleFn = function (fn: String) {
			switch (fn) {
				case "submitBasic":
					submitBasic();
					break;
				case "gotoGateway":
					loadGateway();
					break;
				case "gotoProduct":
					loadProduct();
					break;
				case "updateLocation":
					setAddressDialog.visible = true;
					break;
			}
		};
		const loadGateway = async () => {
			let { result } = await getGatewayList({ sn: state.detail.gatewaySn, pageIndex: 1, pageSize: 1 }, GatewayType.SoftGateway);
			if (result.records?.[0]?.sn) {
				gatewayDialog.detail = result.records?.[0];
				gatewayDialog.visible = true;
			} else {
				showMsg("网关不存在", false);
			}
		};
		const loadProduct = async () => {
			let { result } = await getProductList({
				model: state.detail.productModel,
				deviceType: "device",
				pageIndex: 1,
				pageSize: 1
			});
			if (result.records?.[0]?.id) {
				productDialog.detail = result.records?.[0];
				productDialog.visible = true;
			} else {
				showMsg("产品不存在", false);
			}
		};

		return () => {
			return (
				<div class="modbus-detail-page">
					<GatewayBasicDialog
						width="700px"
						readonly
						title={gatewayDialog.title}
						v-model:visible={gatewayDialog.visible}
						detail={gatewayDialog.detail}
					></GatewayBasicDialog>
					<ProductBasicDialog
						width="700px"
						readonly
						title={productDialog.title}
						v-model:visible={productDialog.visible}
						detail={productDialog.detail}
					></ProductBasicDialog>
					<DialogBox class="set-address-dialog dialog-dense" v-model:visible={setAddressDialog.visible} onConfirm={submitBasic}>
						<>
							<BaseMap
								editerMarker
								detail={state.detail as MarkerDataInfo}
								onLocation={location => (state.detail.location = location)}
								style="height:60vh"
							/>
							<div class="dialog-address-detail">
								{state.detail.location?.address ? (
									<>
										<i class="iconfont iconbx-map"></i>
										<span>
											<span>{state.detail.location?.address}</span>
											<span>
												（{state.detail.location.lng}, {state.detail.location.lat}）
											</span>
										</span>
									</>
								) : null}
							</div>
						</>
					</DialogBox>
					{false && (
						<div class="block-content">
							<Basics detail={state.detail} onLoadMore={handleFn} />
						</div>
					)}
					<div class="block-content">
						<DeviceConfig is6210={props.is6210} isHmp={props.isHmp} />
					</div>
					<div class="block-content mt-4">
						<VariableComp ref={variableEl} onLoadMore={handleFn} />
					</div>
				</div>
			);
		};
	}
});

interface ProfileConfig {
	config: any;
	props: any;
	sensor: any;
}

interface ProfileSimpleParam {
	connectPort: string;
	period: number;
	paramAddr: number;
	paramTimeout: number;
	paramInter: number;
	paramBshort: string;
	paramBint: string;
	paramBfloat: string;
	uploadMode: number;
	uploadPeriod: number;
	uploadCache: number;
}
const DeviceConfig = defineComponent({
	props: {
		isHmp: Boolean,
		is6210: Boolean
	},
	emits: [],
	setup(props) {
		const p = inject<any>(SchemaNodeKey.profile);
		const profile = ref<ProfileConfig>({ config: {}, props: {}, sensor: {} });
		const state = reactive({
			more: false,
			editerConfig: false,
			editerParam: {
				paramAddr: 1,
				paramTimeout: 300,
				paramInter: 50,
				paramBshort: "BA",
				paramBint: "CDAB",
				paramBfloat: "ABCD",
				uploadMode: 2,
				uploadPeriod: 60,
				uploadCache: 100
			} as ProfileSimpleParam,
			modbusTypeList: [] as Dict[],
			modbusType: modbusTcp,
			modbusName: ""
		});
		if (props.isHmp) {
			state.more = true;
		}
		watch(
			() => p.value,
			async () => {
				if (!p.value) {
					return;
				}
				profile.value = p.value.profile;
				initParam();
				let res = await getDictInfo(DictType.ModbusType, profile.value.config.proto /*  || "modbusTcp" */, true);
				state.modbusType = res!.key;
				state.modbusName = res!.label;
			}
		);
		onMounted(async () => {
			state.modbusTypeList = await getDictList(DictType.ModbusType);
			profile.value = p.value.profile;
			initParam();
		});
		const initParam = () => {
			if (!profile.value) {
				return;
			}
			state.editerParam.period = jsonpath.value(profile.value, "$..config.period");
			state.editerParam.connectPort = jsonpath.value(profile.value, "$..config.connect.port");
			state.editerParam.paramAddr = jsonpath.value(profile.value, "$..config.param.addr");
			state.editerParam.paramTimeout = jsonpath.value(profile.value, "$..config.param.timeout");
			state.editerParam.paramInter = jsonpath.value(profile.value, "$..config.param.inter");
			state.editerParam.paramBshort = jsonpath.value(profile.value, "$..config.param.bshort");
			state.editerParam.paramBint = jsonpath.value(profile.value, "$..config.param.bint");
			state.editerParam.paramBfloat = jsonpath.value(profile.value, "$..config.param.bfloat");
			state.editerParam.uploadMode = jsonpath.value(profile.value, "$..config.upload.mode");
			state.editerParam.uploadPeriod = jsonpath.value(profile.value, "$..config.upload.period");
			state.editerParam.uploadCache = jsonpath.value(profile.value, "$..config.upload.cache");
		};
		const submitConfig = async () => {
			let config = { config: {} };
			jsonpath.value(config, "$.config.period", Number(state.editerParam.period));
			jsonpath.value(config, "$.config.connect.port", state.editerParam.connectPort);
			jsonpath.value(config, "$.config.param.addr", Number(state.editerParam.paramAddr));
			jsonpath.value(config, "$.config.param.timeout", Number(state.editerParam.paramTimeout));
			jsonpath.value(config, "$.config.param.inter", Number(state.editerParam.paramInter));
			jsonpath.value(config, "$.config.param.bshort", state.editerParam.paramBshort);
			jsonpath.value(config, "$.config.param.bint", state.editerParam.paramBint);
			jsonpath.value(config, "$.config.param.bfloat", state.editerParam.paramBfloat);
			jsonpath.value(config, "$.config.upload.mode", Number(state.editerParam.uploadMode));
			jsonpath.value(config, "$.config.upload.period", Number(state.editerParam.uploadPeriod));
			jsonpath.value(config, "$.config.upload.cache", Number(state.editerParam.uploadCache));
			let { code, message } = await modifyProfile({
				idSn: jsonpath.value(profile, `$..basic.sn`),
				nodePath: "config",
				data: config.config
			});
			let ok = showTips(code, "操作", message);
			if (ok) {
				//刷新页面
				mittBus.emit("refreshDeviceDetail");
				state.editerConfig = false;
			}
		};

		return () => {
			return (
				<div class="">
					<div class="confit-block">
						{/* hmp不需要设备接入配置 */}
						{props.isHmp ? null : (
							<>
								<div class="flex items-center">
									<div class="block-title">平台接入配置</div>
									{state.editerConfig ? (
										<>
											<el-button class="ml-8" type="primary" onClick={submitConfig}>
												保存
											</el-button>
											<el-button class="ml-4" onClick={() => (state.editerConfig = false)}>
												取消
											</el-button>
										</>
									) : (
										<el-link class="ml-8 iconfont iconedit-3" type="primary" onClick={() => (state.editerConfig = true)}>
											编辑
										</el-link>
									)}
								</div>

								<div class="grid grid-cols-3">
									{false && (
										<div class="flex item">
											<div class="info-title text-right w-1/3">接入协议</div>
											<div class="info-text">
												{!state.editerConfig ? (
													<span>{state.modbusName}</span>
												) : (
													<el-select v-model={state.modbusType}>
														{state.modbusTypeList.map((dict: Dict) => {
															return <el-option label={dict.label} value={dict.key}></el-option>;
														})}
													</el-select>
												)}
											</div>
										</div>
									)}
									<ModbusDevice
										is6210={props.is6210}
										editer={state.editerConfig}
										param={state.editerParam}
										profile={profile.value}
										onSubmit={submitConfig}
									/>
								</div>
							</>
						)}
					</div>
					{/* hmp不需设备接入配置，所以显示全部不需要显示更多 */}
					{props.isHmp ? null : (
						<div>
							<el-link class="mt-8 mb-4" type="primary" onClick={() => (state.more = !state.more)}>
								{state.more ? "更少配置" : "更多配置"}
								<i class={`iconfont ${state.more ? "iconchevrons-up" : "iconchevrons-down"}`}></i>
							</el-link>
							<div style="border-top:1px solid #e8e8e8"></div>
						</div>
					)}
					{state.more && (
						<>
							<div class="confit-block pt-4">
								<div class="flex items-center">
									<div class="block-title">采集配置</div>
									{/* hmp因为没有设备配置，所以这里补充编辑按钮 */}
									{props.isHmp ? (
										state.editerConfig ? (
											<>
												<el-button class="ml-8" type="primary" onClick={submitConfig}>
													保存
												</el-button>
												<el-button class="ml-4" onClick={() => (state.editerConfig = false)}>
													取消
												</el-button>
											</>
										) : (
											<el-link class="ml-8 iconfont iconedit-3" type="primary" onClick={() => (state.editerConfig = true)}>
												编辑
											</el-link>
										)
									) : null}
								</div>
								<div class="grid grid-cols-3">
									<ModbusParam editer={state.editerConfig} param={state.editerParam} profile={profile.value} />
								</div>
							</div>
							<div class="confit-block pt-6 pb-4">
								<div class="flex items-center">
									<div class="block-title">上报配置</div>
								</div>
								<div class="grid grid-cols-3">
									<ModbusReportParam editer={state.editerConfig} param={state.editerParam} profile={profile.value} />
								</div>
							</div>
						</>
					)}
				</div>
			);
		};
	}
});
const ModbusDevice = defineComponent({
	props: {
		is6210: Boolean,
		param: {
			type: Object as PropType<ProfileSimpleParam>,
			default() {
				return {};
			}
		},
		editer: Boolean,
		profile: Object as PropType<ProfileConfig>
	},
	emits: ["submit"],
	setup(props) {
		onMounted(() => {
			props.param.connectPort = props.profile?.config?.connect?.port;
		});
		// const getConnectPort = async () => {
		// 	props.param.connectPort = parseInt(Math.random() * 60000 + "");
		// 	emit("submit");
		// };
		const portTest = () => {
			if (!props.param.connectPort) {
				showMsg("请输入有效端口：1024 ~ 65535", false);
				return;
			}
			portDetect({ port: props.param.connectPort }).then((res: any) => {
				if (res.code == 200) {
					if (res.result && res.result.length) {
						showMsg("端口已被使用，请更换新端口", false);
					} else {
						showMsg("端口未使用", true);
					}
				} else {
					showMsg(res.message || "测试失败", false);
				}
			});
		};
		return () => {
			return (
				// modbusRtu: 设备地址、串口、串口序号、波特率、校验位
				<>
					<div class="flex item">
						<div class="info-title text-right w-1/3">设备地址</div>
						<div class="info-text">
							{!props.editer ? (
								<span>{props.profile?.config?.param?.addr}</span>
							) : (
								<el-input v-model={props.param.paramAddr} placeholder="设备地址: 1"></el-input>
							)}
						</div>
					</div>
					{props.is6210 ? null : (
						<div class="flex item">
							<div class="info-title text-right w-1/3">接入地址</div>
							<div class="info-text flex items-center">
								<span class="flex-none">{window.location.hostname}:</span>
								{/* {props.param.connectPort ? ( */}
								<>
									{!props.editer ? (
										<>
											<span>{props.param.connectPort}</span>
											<span
												class="iconfont iconbx-copy-alt cursor-pointer ml-4"
												title="复制"
												v-copy={`${window.location.hostname}:${props.param.connectPort}`}
											/>
										</>
									) : (
										<>
											<el-input
												type="number"
												v-model={props.param.connectPort}
												placeholder="端口范围：1024 ~ 65535"
												style="margin-left:10px;"
											></el-input>
											<el-link type="primary" onClick={portTest} style="width:128px;margin-left:10px;">
												端口检测
											</el-link>
										</>
									)}
								</>
								{/* // ) : (
								// 	<el-popconfirm title="自动获取连接端口？" popper-class="jsonform-tooltip" onConfirm={getConnectPort}>
								// 		<el-link type="primary">获取端口</el-link>
								// 	</el-popconfirm>
								// )} */}
							</div>
						</div>
					)}
				</>
			);
		};
	}
});
const ModbusParam = defineComponent({
	props: {
		param: {
			type: Object as PropType<ProfileSimpleParam>,
			default() {
				return {};
			}
		},
		editer: Boolean,
		profile: Object as PropType<ProfileConfig>
	},
	emits: [],
	setup(props) {
		const state = reactive({
			modeTypeList: [] as Dict[]
		});
		onMounted(async () => {
			state.modeTypeList = await getDictList(DictType.UploadMode);
		});
		return () => {
			return (
				<>
					{/* 采集参数：采集周期(ms)、间隔时间(ms)、超时时间(ms) 上报参数：上报模式、上报周期(s) */}
					<div class="flex item">
						<div class="info-title text-right w-1/3">采集周期</div>
						<div class="info-text">
							{!props.editer ? (
								<span>{props.profile?.config?.period || 0}ms</span>
							) : (
								<el-input v-model={props.param.period} placeholder="采集周期">
									{{ suffix: () => "ms(毫秒)" }}
								</el-input>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">间隔时间</div>
						<div class="info-text">
							{!props.editer ? (
								<span>{props.profile?.config?.param?.inter || 0}ms</span>
							) : (
								<el-input v-model={props.param.paramInter} placeholder="间隔时间">
									{{ suffix: () => "ms(毫秒)" }}
								</el-input>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">超时时间</div>
						<div class="info-text">
							{!props.editer ? (
								<span>{props.profile?.config?.param?.timeout || "0"}ms</span>
							) : (
								<el-input v-model={props.param.paramTimeout} placeholder="超时时间">
									{{ suffix: () => "ms(毫秒)" }}
								</el-input>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">Short Int字节序</div>
						<div class="info-text">
							{!props.editer ? (
								<>{props.profile?.config?.param?.bshort}</>
							) : (
								<el-select v-model={props.param.paramBshort}>
									{["AB", "BA"].map(data => {
										return <el-option label={data} value={data}></el-option>;
									})}
								</el-select>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">Int字节序</div>
						<div class="info-text">
							{!props.editer ? (
								<>{props.profile?.config?.param?.bint}</>
							) : (
								<el-select v-model={props.param.paramBint}>
									{["ABCD", "CDAB", "BADC", "DCBA"].map(data => {
										return <el-option label={data} value={data}></el-option>;
									})}
								</el-select>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">Float字节序</div>
						<div class="info-text">
							{!props.editer ? (
								<>{props.profile?.config?.param?.bfloat}</>
							) : (
								<el-select v-model={props.param.paramBfloat}>
									{["ABCD", "CDAB", "BADC", "DCBA"].map(data => {
										return <el-option label={data} value={data}></el-option>;
									})}
								</el-select>
							)}
						</div>
					</div>
				</>
			);
		};
	}
});
const ModbusReportParam = defineComponent({
	props: {
		param: {
			type: Object as PropType<ProfileSimpleParam>,
			default() {
				return {};
			}
		},
		editer: Boolean,
		profile: Object as PropType<ProfileConfig>
	},
	emits: [],
	setup(props) {
		const state = reactive({
			modeTypeList: [] as Dict[]
		});
		onMounted(async () => {
			state.modeTypeList = await getDictList(DictType.UploadMode);
		});
		return () => {
			return (
				<>
					{/* 采集参数：采集周期(ms)、间隔时间(ms)、超时时间(ms) 上报参数：上报模式、上报周期(s) */}
					<div class="flex item">
						<div class="info-title text-right w-1/3">上报模式</div>
						<div class="info-text">
							{!props.editer ? (
								<>{state.modeTypeList.find((dict: Dict) => dict.key == props.profile?.config?.upload?.mode)?.label}</>
							) : (
								<el-select v-model={props.param.uploadMode}>
									{state.modeTypeList.map(dict => {
										return <el-option label={dict.label} value={dict.key}></el-option>;
									})}
								</el-select>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">上报周期</div>
						<div class="info-text">
							{!props.editer ? (
								<>{props.profile?.config?.upload?.period}</>
							) : (
								<el-input v-model={props.param.uploadPeriod} placeholder="上报周期">
									{{ suffix: () => "s(秒)" }}
								</el-input>
							)}
						</div>
					</div>
					<div class="flex item">
						<div class="info-title text-right w-1/3">缓存数量</div>
						<div class="info-text">
							{!props.editer ? (
								<>{props.profile?.config?.upload?.cache}</>
							) : (
								<el-tooltip show-after={500} content="0表示不缓存">
									<el-input v-model={props.param.uploadCache} placeholder="缓存数量">
										{{ suffix: () => "条" }}
									</el-input>
								</el-tooltip>
							)}
						</div>
					</div>
				</>
			);
		};
	}
});

const Basics = defineComponent({
	props: {
		detail: {
			type: Object as PropType<Device.ResDeviceInfo>,
			default() {
				return {};
			}
		}
	},
	emits: ["loadMore"],
	setup(props, { emit }) {
		return () => {
			return (
				<>
					<div class="flex justify-between items-center">
						<span class="block-title">基本信息</span>
					</div>
					<div class="grid grid-cols-3">
						<div class="flex item">
							<div class="info-title text-right w-1/3">设备SN</div>
							<div class="info-text">{props.detail.sn}</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">设备名称</div>
							<div class="info-text">{props.detail.name}</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">状态</div>
							<div class="info-text">
								<OnlineStatus v-model={props.detail.onlineStatus} />
								{props.detail.alarmStatus ? (
									<>
										<span class="pr-4">，</span>{" "}
										<span class="status-info">
											<span class={["dot", EffectType.danger]} />
											<span>告警中</span>
										</span>
									</>
								) : null}
							</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">所属分组</div>
							<div class="info-text">{props.detail.deptName}</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">接入网关</div>
							<div class="info-text">
								<el-link type="primary" underline={false} onClick={() => emit("loadMore", "gotoGateway")}>
									{props.detail.gatewaySn}
								</el-link>
							</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">产品模型</div>
							<div class="info-text">
								<el-link type="primary" underline={false} onClick={() => emit("loadMore", "gotoProduct")}>
									{props.detail.productModel}
								</el-link>
							</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">更新时间</div>
							<div class="info-text">{props.detail.updateTime}</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">掉线时间</div>
							<div class="info-text">{props.detail.logoutTime}</div>
						</div>
						<div class="flex item">
							<div class="info-title text-right w-1/3">创建时间</div>
							<div class="info-text">{props.detail.createTime}</div>
						</div>

						<div class="flex item col-span-3">
							<div class="info-title text-right" style="width: calc(33.3333% / 3)">
								位置
							</div>
							<div class="info-text flex">
								<el-link type="primary" underline={false} onClick={() => emit("loadMore", "updateLocation")}>
									<i class="iconfont iconbx-map"></i>
									{props.detail.location?.address ? (
										<span>
											<span>{props.detail.location?.address}</span>
											<span>
												（{props.detail.location.lng}, {props.detail.location.lat}）
											</span>
										</span>
									) : (
										"--"
									)}
								</el-link>
							</div>
						</div>
					</div>
				</>
			);
		};
	}
});

import { getGatewayList } from "@/api/modules/iot/gateway";
import { getProductList } from "@/api/modules/iot/product";
import { addInfo, delInfo, exportVariableExcel, getPageList, importVariableExcel, modInfo } from "@/api/modules/iot/variable";
import { modifyProfile } from "@/api/modules/model/profile";
import DialogBox from "@/components/DialogBox";
import BaseMap from "@/components/Map/antvl7/BaseMap";
import ProTable from "@/components/ProTable/index.vue";
import { ColumnProps } from "@/components/ProTable/interface";
import SensorHistory from "@/components/Sansan/Model/device/SensorHistory";
import UploadFile from "@/components/Upload/UploadFile.vue";
import { useAuthButtons } from "@/hooks/useAuthButtons";
import { Dict, DictType, getDictInfo, getDictList } from "@/utils/cacheUtil";
import { MarkerDataInfo } from "@/utils/gps";
import VariableDialog from "@/views/iot/variable/components/basicDialog";
import ParamSend from "./paramSend";
import { PublicStore } from "@/stores/modules/public";
const VariableComp = defineComponent({
	emits: ["loadMore"],
	setup(props, { expose }) {
		const publicStore = PublicStore();
		const state = reactive({
			detail: {} as Device.ResDeviceInfo
		});
		const btnList = ref<any>([]);
		const batchBtnList = ref<any>([]);
		const paramsend = ref();
		onMounted(async () => {
			// 获取页面按钮权限
			let res = await useAuthButtons(AuthBtns.iotVriable);
			btnList.value = res.filter((item: any) => !item.btnGroup);
			batchBtnList.value = res.filter((item: any) => item.btnGroup == "3");
		});

		const initParam = reactive({ pageSize: 15 } as any);

		const dataCallback = (data: any) => {
			return {
				datalist: data.records,
				total: data.total || 0,
				pageIndex: data.current,
				pageSize: data.size
			};
		};

		const getTableList = async (params: any) => {
			params.sn = state.detail.sn;
			if (params.sn) {
				return getPageList(params);
			} else {
				return { result: { records: [] } };
			}
		};
		const initLoad = (detail: Device.ResDeviceInfo) => {
			state.detail = detail;
			proTable.value.clearSelection();
			proTable.value.reset();
		};
		const uploadFileEl = ref();
		const sensorHistoryEl = ref();
		const detailDialog = reactive<any>({
			title: "变量配置",
			visible: false,
			detail: {}
		});
		const clickBtn = async (fn: string, row: any) => {
			let selected: Variable.ResVariable[] = row.selectedList ? row.selectedList : [row];
			switch (fn) {
				case "detail":
				case "mod":
					if (selected.length != 1) {
						showMsg("请选择一条记录", MessageType.warning);
						return;
					}
					detailDialog.detail = { ...selected[0] };
					detailDialog.visible = true;
					break;
				case "copy":
					if (selected.length != 1) {
						showMsg("请选择一条记录", MessageType.warning);
						return;
					}
					detailDialog.detail = { ...selected[0] };
					detailDialog.detail.key = detailDialog.detail.key + "_copy";
					detailDialog.detail.label = detailDialog.detail.label + "_copy";
					detailDialog.visible = true;
					break;
				case "add":
					detailDialog.detail = { sn: state.detail.sn };
					detailDialog.visible = true;
					break;
				case "del":
					if (!selected.length) {
						showMsg("请选择要删除的数据", MessageType.warning);
						return;
					}
					confirm({ content: "删除后无法找回，确定删当前操作" }).then(flag => {
						flag && submitDel(selected);
					});
					break;
				case "sensorData":
					loadSensorData(selected[0]);
					break;
				case "import":
					uploadFileEl.value.selectingFile();
					break;
				case "export":
					let { data, filename } = await exportVariableExcel({ sns: state.detail.sn });
					exportExcel(data, filename);
					break;
				case "send":
					if (!selected.length) {
						showMsg("请选择要下发的数据", MessageType.warning);
						return;
					}
					paramsend.value.Init(state.detail, selected, proTable.value.getTableList);
					break;
			}
		};
		const loadSensorData = (row: Variable.ResVariable) => {
			let arr = row.key.split(".");
			let param = {
				dataPath: row.key,
				dataType: row.type,
				dataKey: arr[arr.length - 1],
				dataValue: row.value,
				schemaInfo: { title: row.label }
			};
			sensorHistoryEl.value.loadData(param, row.sn);
		};
		// 表格配置项
		const columns: ColumnProps[] = [
			{ type: "selection", fixed: "left", width: "auto" },
			{ prop: "label", label: "变量名称", sortable: true /*, search: { el: "input" } */ },
			{ prop: "key", label: "变量标识", sortable: true },
			{ prop: "type", label: "数据类型" },
			{ prop: "value", label: "实时值" },
			{ prop: "tags", label: "变量标签" },
			{ prop: "updateTime", label: "更新时间", width: 170, sortable: true }
		];

		const proTable = ref<any>();
		const submitDel = async (dataInfo: Variable.ResVariable[]) => {
			let delParam: Variable.DelVariable = { snKey: {} };
			dataInfo.forEach(item => {
				if (!delParam.snKey[item.sn]) {
					delParam.snKey[item.sn] = [];
				}
				delParam.snKey[item.sn].push(item.key);
			});
			let res = await delInfo(delParam);
			let ok = showTips(res.code, "删除", res.message);
			if (ok) {
				proTable.value.clearSelection();
				proTable.value.getTableList();
			}
		};
		const submitDetail = async () => {
			let api = detailDialog.detail.id ? modInfo : addInfo;
			let res = await api(detailDialog.detail);
			let ok = showTips(res.code, "变量配置操作", res.message);
			if (ok) {
				detailDialog.visible = false;
				proTable.value.getTableList();
			}
		};
		const handleChange = (e: any) => {
			initParam.sortField = e.prop;
			initParam.sortOrder = e.order == "ascending" ? "asc" : e.order == "descending" ? "desc" : "";
			// proTable.value.getTableList();
		};
		expose({ initLoad });
		return () => {
			return (
				<div>
					<div class="flex justify-between items-center mb-2">
						<div class="block-title">变量列表</div>
						<div>
							{btnList.value?.map((item: any) => {
								return (
									<el-button
										onClick={() => clickBtn(item.path, { selectedList: proTable.value.selectedList })}
										type={item.btnClass}
									>
										<i class={`iconfont ${item.icon}`}></i>
										{item.menuName}
									</el-button>
								);
							})}
							{batchBtnList.value.length ? (
								<el-dropdown
									trigger="click"
									v-slots={{
										dropdown: () => {
											return (
												<el-dropdown-menu>
													{batchBtnList.value.find((item: any) => item.path == "import") ? (
														<>
															<UploadFile
																style="display: none;"
																ref={uploadFileEl}
																api={importVariableExcel}
																headers={{ Authentication: publicStore.token }}
															/>
															<el-dropdown-item onClick={() => clickBtn("import", { selectedList: proTable.value.selectedList })}>
																批量导入
															</el-dropdown-item>
														</>
													) : null}
													{batchBtnList.value.find((item: any) => item.path == "export") ? (
														<el-dropdown-item onClick={() => clickBtn("export", { selectedList: proTable.value.selectedList })}>
															批量导出
														</el-dropdown-item>
													) : null}
												</el-dropdown-menu>
											);
										}
									}}
								>
									<el-button type="primary" plain>
										批量操作<span class="iconfont iconchevron-down pl-1"></span>
									</el-button>
								</el-dropdown>
							) : null}
						</div>
					</div>
					<SensorHistory ref={sensorHistoryEl} />
					<VariableDialog
						width="850px"
						devicePage
						title={detailDialog.title}
						v-model:visible={detailDialog.visible}
						detail={detailDialog.detail}
						onSubmit={submitDetail}
					></VariableDialog>
					<ProTable
						ref={proTable}
						title={btnList.value.length ? "" : "列表管理"}
						columns={columns}
						requestApi={getTableList}
						initParam={initParam}
						dataCallback={dataCallback}
						ignoreInit={true}
						showHeader={false}
						onSortChange={handleChange}
					>
						{{
							key: (scope: any) => {
								return (
									<div class="truncate cursor-pointer primary-color" onClick={() => clickBtn("detail", scope.row)}>
										{scope.row.key}
									</div>
								);
							},
							tags: (scope: any) => {
								return (
									<>
										{scope.row.param?.tags?.map((v: string) => {
											return (
												<el-tag class="mr-1" closable={false} disable-transitions={false}>
													{v}
												</el-tag>
											);
										})}
									</>
								);
							},
							value: (scope: any) => {
								return (
									<div class="truncate cursor-pointer primary-color" onClick={() => clickBtn("sensorData", scope.row)}>
										{scope.row.value || "--"}
									</div>
								);
							},
							onlineStatus: (scope: any) => {
								return <OnlineStatus v-model={scope.row.onlineStatus} onlineLabel="运行中" offlineLabel="未启动" />;
							}
						}}
					</ProTable>
					<ParamSend ref={paramsend} />
				</div>
			);
		};
	}
});
